<?php
namespace Com\Pay;
class PFPay{
    // v1

    private $config = array();

    public function __construct($mchData){
        $this->config = $mchData;
    }

    /*生成支付连接*/
    public function getUrl($order_info){
        // 此时 $this->config['mch_id'] 是二级商户号
        $merchantCode = $this->config['appid'];
        $notifyUrl = S_URL . '/Api/NotifyCallback/PFPayNotify?subMchId=' . $this->config['mch_id'];
        $order_sn = $order_info['ordernumber'];
        $price = $order_info['paymoney'] * 100;
        $post_data = array(
            'requestNo' =>   $order_sn,
            'version'    =>    'V1.1',
            'productId'     =>  $order_info['productId'],
            "transId"  =>  $order_info['transId'],
            "clientIp"  =>  get_client_ip(),
            "merNo"  =>  $merchantCode,
            "subMchId"     => $this->config['mch_id'],
            'orderDate'   => date('Y-m-d'),
            'orderNo'   => $order_sn,
            'returnUrl'   => $order_info['return_url'],
            'notifyUrl'   => $notifyUrl,
            'transAmt'   => $price,
            'commodityName'   => "Cbpay"
        );

        if($order_info['subOpenId'] != '') $post_data['subOpenId'] = $order_info['subOpenId'];
        $post_data['signature'] = urlencode(encrypt::sign(Util::SinParamsToString($post_data) , $merchantCode));
        $res = $this->postData('http://spdbweb.chinacardpos.com/payment-gate-web/gateway/api/backTransReq' , util::arrayToString($post_data));
        $params=array();
        parse_str($res,$params);

//        var_dump($params);exit;

        // 310440300116879  ==> 66249298  66541601   66537074  66537107  四个二级商户号

        // 310440300116924  ==>

        if($params['formfield'] != '') {
            return base64_decode($params['payInfo']);
        }elseif( $params['codeUrl'] != '' ){
            return base64_decode($params['codeUrl']);
        }
        return '';
    }

    //报备支付宝二级商户号
    public function getAlisubMchid($order_info){
        $url = "http://spdbweb.chinacardpos.com/payment-gate-web/gateway/api/backTransReq";
        $addressInfo=array(
            'source' => '200020020202020',
            'province_code' => '360000',
            'city_code'=>'371000',
            'district_code' => '371002',
            'address'=>'福建省宁德市福安市阳头街道富阳路26号',
        );

        //
        $contactInfo=array(
            // 商户联系信息
            'name'=>'6217231408000910968', //银行账号
            'phone'=>'刘霞', //账户名称
            'cardBankNo'=>'308584001571', //联行号
            'type' => 'CONTROLLER'
        );
        $bankCardInfo = array(
            // 结算信息
            'card_no' => '6217231408000910968' ,
            'card_name' => '傅天赐'
        );
        $data = array(
            'requestNo' => $order_info['ordernumber'],
            'version' => 'V1.1',       //发起方系统流水号
            'transId' => 18,
            'payWay' => 'ALIPAY',
            'merNo' => '310440300116879',
            'subMechantName' => '广州市天河区林和卓信电子经营部',
            'business' => 304,
            'subMerchantShortname' => '畅宝超市',
            'contact' => '傅天赐',
            'contactPhone' => '17750935530',
            'contactEmail' => '2127795963@qq.com',
            'merchantRemark' => '商户号报备3',
            'servicePhone' => '17750935530',
            'contactInfo' => json_encode($contactInfo),
            'addressInfo' => json_encode($addressInfo),
            'bankCardInfo' => json_encode($bankCardInfo),
        );

        // 公众号信息报备
        $data1 = array(
            'requestNo' => $order_info['ordernumber'],
            'version' => 'V1.1',       //发起方系统流水号
             'transId' => 28,
             'payWay' => 'WX',
            'merNo' => '310440300116879',
            'subMchId' => "66537107",
//            'jsApiPath' => 'http://www.gongzhiwei.cn/Pufa/',
            'subAppId' => 'wx74bad5e8624edcbb',
        );

        $data['signature'] = urlencode(encrypt::sign(Util::SinParamsToString($data) , '310440300116879'));
        $res = $this->postData($url ,  util::arrayToString($data));
        $params = array();
        parse_str($res ,$params);
        var_dump($params);
        exit;
    }

   private function postData($url, $data){
        $ch = curl_init();
        $timeout = 300;
        curl_setopt($ch,CURLOPT_HTTPHEADER,array(
            "content-type: application/x-www-form-urlencoded; 
charset=UTF-8"
        ));
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_REFERER, $url);   //站点
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        $handles = curl_exec($ch);
        curl_close($ch);
        return $handles;
    }

    //回调方法，把返回数据处理成统一规定返回
    public function response(){
        $data = parseData();
        unset($data['subMchId']); // 删除自己带的参数在进行验签
        $Sign = $data['signature'];
        // 进行签名验证
        $query = Util::SinParamsToString($data);
        $VerifySignRes =  encrypt::rsaVerify($query ,$Sign , $data['merNo']);
        if($VerifySignRes){
            // 验签成功
            if($data['respCode'] == '0000'){
                return true;
            }else{
                return false;
            }
        }else{
            // 失败
            return false;
        }
    }

}

class encrypt{
    /**
     * 使用空格替换换行符
     * @param string string_before
     * @return string string_after
     */
   public static function string_replace($string_before){
        $string_after = str_replace('%','PP',$string_before);
        $string_after = str_replace('&','AND',$string_after);
        $string_after = str_replace(',','',$string_after);
        return $string_after;
    }


    public static function rsaVerify($prestr, $sign , $mch_id) {
        $sign = base64_decode($sign);
        $pkeyid = openssl_get_publickey(file_get_contents(getcwd().'/ThinkPHP/Library/Vendor/pufaPem/'.$mch_id.'_pub.pem'));
        if ( $pkeyid ) {
            $verify = openssl_verify($prestr, $sign, $pkeyid);
            openssl_free_key($pkeyid);
        }

        if($verify == 1){
            return true;
        }else{
            return false;
        }
    }


    public static function pubkeyEncrypt($data,$panText,$pubkey){
        openssl_public_encrypt($data,$panText,$pubkey,OPENSSL_PKCS1_PADDING);
        return	strtoupper(bin2hex($panText));
    }

    public static function getBytes($string) {
        $bytes = array();
        for($i = 0; $i < strlen($string); $i++){
            $bytes[] = ord($string[$i]);
        }
        return $bytes;
    }

   public static function sign($data , $mch_id) {
        //读取私钥文件
        //注意所放文件路径
       /** @var TYPE_NAME $priKey */
       $priKey = file_get_contents(getcwd().'/ThinkPHP/Library/Vendor/pufaPem/'. $mch_id . '_prv.pem');

        //转换为openssl密钥，必须是没有经过pkcs8转换的私钥
        $res = openssl_get_privatekey($priKey);
        //调用openssl内置签名方法，生成签名$sign
        openssl_sign($data, $sign, $res);

        //释放资源
        openssl_free_key($res);

        return base64_encode($sign);
    }


}

class Util{
    /**
    验签所需字符串特殊处理函数
     */
   public static function SinParamsToString($params) {
        $sign_str = '';
        // 排序
        ksort($params);

        foreach ($params as $key =>$val){
            if ($key == 'signature'){
                continue;
            }
            $sign_str .= sprintf ( "%s=%s&", $key, $val );
        }
        return substr ( $sign_str, 0, strlen ( $sign_str ) - 1 );
    }





    /**
    最终抛送数据所需字符串特殊处理函数
     */
    public static function arrayToString($params){
        $sign_str = '';
        // 排序
        ksort ( $params );
        foreach ( $params as $key => $val ) {

            $sign_str .= sprintf ( "%s=%s&", $key, $val );
        }
        return substr ( $sign_str, 0, strlen ( $sign_str ) - 1 );

    }

}
